package stream;

import utils.Print;

import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class SplitList {
    public static <T> List<List<T>> splitNormal(List<T> input, Predicate<T> pred){
        List<List<T>> result = new ArrayList<>();
        int start = 0;

        for(int cur = 0; cur < input.size(); cur++){
            if(pred.test(input.get(cur))){
                result.add(input.subList(start, cur));
                start = cur + 1;
            }
        }
        result.add(input.subList(start, input.size()));

        return result;
    }

    public static <T> List<List<T>> splitStream(List<T> input, Predicate<T> pred){
        int[] edgs = IntStream.range(-1, input.size() + 1)
                .filter(i -> i == -1 || i == input.size() || pred.test(input.get(i)))
                .toArray();

        return IntStream.range(0, edgs.length - 1)
                .mapToObj(k -> input.subList(edgs[k] + 1, edgs[k + 1]))
                .collect(Collectors.toList());
    }

    public static void main(String[] args){
        char[] values = {'a', 'e', '#', '3', '#', 'b', '4', '#', '9'};

        //List<Character> list = Arrays.asList(chars); // this does not compile,
        List<Character> test1 = new ArrayList<Character>();
        for (char c : values) {
            test1.add(c);
        }

        //Stream<Character> cStream = Stream.of(list);
        // Stream<Character> cStream = Arrays.stream(list);
        List<Character> test2 = CharBuffer.wrap(values).chars()
                .mapToObj(ch -> (char) ch)
                .collect(Collectors.toList());

        List<Character> test3 = IntStream.range(0, values.length)
                .mapToObj(i -> values[i])
                .collect(Collectors.toList());;

        Predicate predicate = new Predicate<Character>() {
            @Override
            public boolean test(Character c) {
                return c == '#';
            }
        };

        Print.printList(splitNormal(test1, predicate));

        Print.printList(splitStream(test2, predicate));

        Print.printList(splitStream(test3, predicate));
    }
}
